/* 
 * File:   packageMerge.c
 * Author: FENG Xu <fengxu1989@gmail.com>
 *
 * Created on May 29, 2012, 5:47 PM
 */
#include <stdio.h>
#include <stdlib.h>
#include "../h/packageMerge.h"

/*
 * Fonction compteur: renvoie le nombre de paires contenant la feuille
 */
int compter(ajout* ajouts, unsigned char s){
    int i;
    listeSP p; /* p est un pointeur qui va parcourir la liste des symboles pour chaque element de la table des ajouts */
    int compteur =0; /* On initialise le compteur a 0 */
    
    for(i=0; i<LMAX; i++){
		/* parcours de la table d'ajouts (parcours vertical) */
        for(p = (ajouts[i]->tete); p!=NULL; p=p->suivant ){ /* parcours de la liste des symboles (parcours horizontal) */
            if (p->symbole==s) compteur++;
        }
    }
    return compteur;
}

/*
 * calculer le nombre de symboles.
 */
int calculerNbSymboles(ajout* tab){
	int nbSymbole=0;
	int i=0;
	while(tab[i]!=NULL) i++;
	if(tab[i]==NULL) nbSymbole=i;
	return nbSymbole;
}

/*
 * Fonction package 
 */
listeSL package(ajout* feuilles){
    tabAjouts ajouts={NULL};
	tabAjouts liste={NULL};
    int i,j;
    int nbSymboles;
    
    listeSL lsl=NULL;
    listeSL courantLSL=lsl;
    listeSP courantLSP;
    int lg, l;
    int k;
	
    nbSymboles=calculerNbSymboles(feuilles);
    
    for(l=2; l<=LMAX; l++){
		for(i=0; liste[i]!=NULL && i<LMAX; i++){
			liste[i]=NULL;
		}
		printf("La liste est initialisee.\n");
		for(i=0; feuilles[i]!=NULL && i<LMAX; i++){
			insererEnTriant(liste,feuilles[i]); 
			printf("%d %d %p\n",liste[i]->nbSymboles,liste[i]->poidsSomme,liste[i]->tete);
		}
		printf("Les feuilles sont bien remplies.\n");
        for(j=0; ajouts[j]!=NULL && j<LMAX/2; j++){
            insererEnTriant(liste,ajouts[j]);
			if(liste[i+1+j]!=NULL && liste[i+1+j]->tete!=NULL)printf("BON\n");else printf("err\n");
			printf("%d %d %p\n",liste[i+1+j]->nbSymboles,liste[i+1+j]->poidsSomme,liste[i+1+j]->tete);
        } 
		printf("Les ajouts sont bien remplis.\n");
		for(i=0; ajouts[i]!=NULL && i<LMAX; i++){
			ajouts[i]=NULL;
		}
		printf("Les ajouts sont vides.\n");
		for(i=0; (2*i+1)<LMAX && liste[i*2]!=NULL && liste[i*2+1]!=NULL; i++){
			ajouts[i]=appairer(liste,i);
			printf("%d %d %p\n",ajouts[i]->nbSymboles,ajouts[i]->poidsSomme,ajouts[i]->tete);
		}
		printf("Les ajouts sont bien appaires.\n");
    }
	
    /* On parcourt maintenant les N-2 paires de ajouts pour determiner la longueur de chaque symbole */
    for(k=0; k<nbSymboles; k++){
		printf("BON1\n");
        unsigned char s=feuilles[k]->tete->symbole; 
        for (i=0; i < (nbSymboles-2) && ajouts[i]!=NULL; i++){
			printf("BON2\n");
		    for(courantLSP=(ajouts[i]->tete); courantLSP!=NULL; courantLSP=courantLSP->suivant){
				printf("BON3\n");
		        lg = compter(ajouts,s)+1;
		    }
        }
		courantLSL=newLSL(s,lg,NULL);
        courantLSL=courantLSL->suivant;
    }
	printf("%d\n",lsl->longueur);
	trierLSL(lsl);
	printf("%d\n",lsl->longueur);

    return lsl;
}

/*
 * Cette fonction renvoie le dernier element de la liste symbole/ longueur. On suppose que la liste est deja triee. 
 */
int recupererDernier(listeSL list){
     listeSL cour; /* declaration d'un pointeur de parcours */
	 int lmax;
     for(cour=list ; cour!=NULL; cour=cour->suivant){ /* parcours de la liste symbole/longueur */
         if (cour->suivant == NULL) lmax=cour->longueur; /* On retourne alors sa valeur qui est donc la valeur de la longueur maximale */
     }
	 return lmax;
} 

/*
 * Fonction qui permet de determiner pour chaque longueur, le nombre d'elements qui ont sa valeur 
 */
int compterEntier (listeSL lsl, int l){
    int compteur=0; /* On initialise le compteur a 0*/
    listeSL j; /* on declare un pointeur de listeSL*/
    
    for (j=lsl ; j!=NULL; j=j->suivant){ /* On parcourt la liste symbole longueur*/   
		if (j->longueur == l) compteur++;/* On compare la longueur de chaque symbole a la longueur donnee */
    }
    return compteur;
}

/*
 * Fonction qui prend en parametre une liste symbole/longueur et qui renvoie un tableau longueur/nombre 
 */
int* toTabLN(listeSL sl){
 
	int i;
	int taille=recupererDernier(sl)+1; /* On calcule la taille du tableau a partir de la plus grande valeur de la liste symbole / longueur */
	int* tab=(int*)calloc(taille, sizeof(int)); /* A partir de la taille obtenue, on constrruit le tableau. Cela permet d'economiser de la memoire */
	listeSL l; /* On cree un pointeur de type listeSL */
	
	for (i=0; i< taille ; i++){ /* Parcours du tableau */
		for(l=sl ; l!=NULL; l=l->suivant){/* parcours de la liste symbole/ longueur */
          tab[i]=compterEntier(sl, i); /* Pour chaque indice i, on fait un rappel de la fonction countEntier qui determine combien de fois, cet indice est present dans la liste symbole /longueur  */
		}
	}
	return tab; /* On retourne le tableau rempli avec le nombre d'apparition de chaque longueur */
}

